package com.hsmpay.yl8583.service;

import com.hsmpay.utils.DesUtil;
import com.hsmpay.utils.NumberUtil;
import com.hsmpay.utils.WriteFile;
import com.hsmpay.utils.system.ConConfig;
import com.hsmpay.yl8583.utils.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.ApplicationContext;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Map;

public class UinpaySocketToBoss {
	private ApplicationContext act;
	static WriteFile wf = new WriteFile("ds_Uinpay");
	public static String debug = ConConfig.getAttribute("UINPAY_DAISHOU_DEBUG_STATUS");
	
	//尤银银联生产平台
	//static String ipAdd="116.228.144.78";
	//static String IPort="56603";
	static String ipAdd="";
	static String IPort="";
	String itimeout="60000";
	
	String ShopCode = "108291154111807";//商户号
	String PosNo = "20000081";			//终端号
	
	String tpdu = "6000030000";
	String header = "603100310001";
	String batch = "000001"; 			 // 批次号
	String serialNumber = "100013"; 	 // 系统跟踪号(POS中心流水号)
	String operator="001";				 //操作员
	//ZMK密文密钥
//	String ZMKKey="F1B09DC47C3CC6DA7BD072B6CF9C5181";
	//密文报文密钥
	String MacKey="CD3BEC830CAD5EA767174CC42C3C930E";
	//密文密码密钥
	String PinKey="F033F39A20309A2DC6968C1A07E6120E";
	//密文磁道密钥
	String trkKey="AE50A271FB4811631E62FD28E19CA04E";

	//主密钥
	String MasterKey="";
	
	String MuKey = "11111111111111112222222222222222";
	
	byte[] bitmap = new byte[8];

	String logCode = NumberUtil.getLogCode();

//	static{
//		if("1".equals(debug)){
//			ipAdd="101.251.110.53";
//			IPort="6603";
//		}
//	}
	
	/**
	 * 构造函数
	 * @param ShopCode
	 * @param PosNo
	 * @param batch
	 * @param MasterKey
	 * @param PinKey
	 * @param MacKey
	 * @param trkKey
	 */
	public UinpaySocketToBoss(String ShopCode, String PosNo, String batch, String MuKey, String MasterKey, String PinKey, String MacKey, String trkKey, Map<String,String> config){
		/*
		* 	优银通道参数
		* */
		if (config != null){
			this.ipAdd = config.containsKey("ip") ? config.get("ip") : "101.251.110.53";
			this.IPort = config.containsKey("port") ? config.get("port") : "6603";
		}
		this.ShopCode = ShopCode;
		this.PosNo = PosNo;
		
		this.batch = batch;
		this.MuKey = MuKey;
		this.MasterKey = MasterKey;
		this.PinKey = PinKey;
		this.MacKey = MacKey;
		this.trkKey = trkKey;
		if(StringUtils.isEmpty(batch.trim())){
			this.batch = "000001";
		}
		if(StringUtils.isNotBlank(MuKey) && StringUtils.isNotBlank(MasterKey))
			this.MasterKey = DesUtil.decode3DES(MasterKey, MuKey);
		
		
		act = SpringUtil.getApplicationContext();//new ClassPathXmlApplicationContext("anxinybConfig.xml");

        wf.log("tpdu:" + this.tpdu, "调试");
		wf.log("ShopCode(商户号):" + this.ShopCode, "调试");
		wf.log("PosNo(终端号):" + this.PosNo, "调试");
		wf.log("batch(批次号):" + this.batch, "调试");
		wf.log("MuKey:" + this.MuKey, "调试");//数据库保存是 主秘钥
		wf.log("ZMKKey:" + this.MasterKey, "调试");
		wf.log("PinKey:" + this.PinKey, "调试");
		wf.log("MacKey:" + this.MacKey, "调试");
		wf.log("trkKey:" + this.trkKey, "调试");
	}
	

	/**
	 * 通信检测(0000)
	 * 
	 * @return 是否正常
	 */
	public String detection(byte[] sendStr) {
//		SendSocket send = new SendSocket(ipAdd, IPort, itimeout,wf);
		SendSocket send = new SendSocket(ipAdd, IPort, itimeout,wf);
		return send.detection(sendStr);
	}

	public String AddSerialNumber(String SerialNumber) {
		int OldLen = 6;
		String NewStr = (Integer.parseInt(SerialNumber) + 1) + "";
		int NewLen = NewStr.length();
		if (NewLen == 7) {
			NewStr = "000000";
			NewLen = 6;
		}
		for (int i = 0; i < (OldLen - NewLen); i++) {
			NewStr = "0" + NewStr;
		}
		return NewStr;
	}

	public String unAddSerialNumber(String SerialNumber) {
		int OldLen = 6;
		String NewStr = "";
		if (SerialNumber.equals("000000")) {
			NewStr = "999999";
		} else {
			NewStr = (Integer.parseInt(SerialNumber) - 1) + "";
		}
		int NewLen = NewStr.length();
		for (int i = 0; i < (OldLen - NewLen); i++) {
			NewStr = "0" + NewStr;
		}
		return NewStr;
	}

	// 将字符串按指定长度返回,不足位数在前面加0。
	public String GetNewStr(String str, int len) {
		String NewStr = "";
		for (int i = 0; i < len - str.length(); i++) {
			NewStr += "0";
		}
		NewStr += str;
		return NewStr;
	}
	//获取字符串字节长度(双字节长度为2,单字节长度为1)
	public int strlen(String str){ 
		int len=0;
	    try {
			len= (new String(str.getBytes("GBK"), "ISO-8859-1")).length();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} 
		return len;
	}
	//获取字符串中单双字节的个数并以";"分隔返回。
	public String getCharString(String inputText)
	{
		int count = 0; 
		int chCharCount = 0;
		int dconut=0;
		char[] charArray = inputText.toCharArray(); 
		for (int i = 0; i < charArray.length; i++) { 
			char cn = charArray[i]; 
			byte[] bytes = (String.valueOf(cn)).getBytes(); 
			if (bytes.length == 1) { //单字节字符
				dconut++;
				//英文字符 
				//int ascii = bytes[0]; 
			}else if (bytes.length == 2) { //双字节字符 
				count++; 
				int hightByte = 256 + bytes[0]; 
				int lowByte = 256 + bytes[1]; 
				int ascii = (256 * hightByte + lowByte) - 256 * 256; 
				if (ascii >= -20319 && ascii < -10247) { //中文字符 
					chCharCount++; 
				} 
			} 
		} 
//		System.out.println( "共有 " + dconut + " 个单字节字符! "); 
//		System.out.println( "共有 " + count + " 个双字节字符! "); 
//		System.out.println( "共有 " + chCharCount + " 汉字! "); 
		return dconut+";"+count;
	}
	/**
	 * 终端签到
	 * 
	 * @return 批次号
	 * @throws Exception
	 */
	public String Login0800(String serialNumber) throws Exception {
		try{
			String LoginMsg = "0";
			String TYPE_ID = "0800";
			wf.log("-------------------请求包域值信息-------------------",	"调试");
			Package64 pk = new Package64();
			pk.setTpdu(PackageUtil.hexStringToByte(this.tpdu));
			pk.setHeader(PackageUtil.hexStringToByte(this.header));
			pk.setMessagetype(PackageUtil.hexStringToByte(TYPE_ID));
			wf.log("[tpdu]=" + this.tpdu, "调试");
			wf.log("[header]=" + this.header, "调试");
			wf.log("[messagetype]=" + TYPE_ID, "调试");
			// 11、41、42、60、63
			String str = "bit11,bit41,bit42,bit60,bit63";
			for (String one : str.split(",")) {
				Field filed = (Field) act.getBean(one);
				if(one.equals("bit11"))
				{
					filed.valueof(serialNumber);
				}else if (one.equals("bit41")) {
					filed.valueof(this.PosNo);
				}else if (one.equals("bit42")) {
					filed.valueof(this.ShopCode);
				} else if (one.equals("bit60")) {
					filed.valueof("00" + this.batch + "004");
				} else if (one.equals("bit63")) {
					filed.valueof(PackageUtil.getCnASCII(this.operator));
				}
				pk.getData().put(filed.getFiledNumber(), filed);
			}
			this.bitmap = Package64.CreateBitMap(pk.getData().keySet());
			wf.log("[bitmap]=" + PackageUtil.byte2hex(this.bitmap),"调试");
			for (Integer one : pk.getData().keySet()) {
				wf.log("bit" + one + ":"+ PackageUtil.byte2hex(pk.getData().get(one).toByte()),"调试");
			}
			wf.log("----------------------------------------------------", "调试");
			pk.setBitmap(this.bitmap);
			byte[] pk_byteArray = pk.package64();
			ByteBuffer buff = ByteBuffer.allocate(pk_byteArray.length + 2);
			buff.putShort((short) pk_byteArray.length);
			buff.put(pk_byteArray);
	
	
			wf.log("请求包:长度 " + pk_byteArray.length + " 数据 "	+ PackageUtil.byte2hex(buff.array()), "调试");
			LoginMsg = detection(buff.array());
			wf.log("响应包:长度 " + LoginMsg.length() / 2 + " 数据 "+ LoginMsg, "调试");
			if ((!LoginMsg.equals("-1")) && (!LoginMsg.equals(""))) {
				LoginMsg = "0"+ Package64.UnPackage(PackageUtil.hexStringToByte(LoginMsg), "39,60,62",wf);
			
				String startMsg = LoginMsg.substring(0, LoginMsg.lastIndexOf("_"));
				String bit62 = LoginMsg.substring(LoginMsg.lastIndexOf("_")+1);
				System.out.println("bit62 = "+bit62);
				//bit62 = PackageUtil.toStringHex(bit62);//转为BCD 16进制
				//注意 LL+主秘钥+校验码+LL+mac秘钥+校验码+LL+pin秘钥+校验码+LL+trc秘钥+校验码
				bit62 = bit62.substring(2, 34)+"_"+bit62.substring(102,134)+"_"+bit62.substring(52,84)+"_"+bit62.substring(152,184);
				LoginMsg = startMsg+"_"+bit62;
			
			} else {
				return "-1_";
			}
			wf.log("银联签到返回数据:" + LoginMsg, "调试");
			return LoginMsg;
		}catch(Exception e){
			throw e;
		}
	}
	/**
	 * 银行卡余额查询
	 * 
	 * @param trk2
	 *            二磁道数据
	 * @param trk3
	 *            二磁道数据
	 * @param des_pin
	 *            卡交易密码
	 * 
	 * @return 订单信息
	 * @throws Exception
	 */
	public String Query(String trk2, String trk3, String pin,String accountNumber,String serialNumber,String bit23,String bit55,String bit14)throws Exception {
		try{
			String des_pin= TestDes.MakeDesPin(accountNumber, pin, PinKey, MasterKey);
			System.out.println("des_pin:"+des_pin);
			
			String QueryMsg = "";
			String TYPE_ID = "0200";
			wf.log("-------------------请求包域值信息-------------------","调试");
			Package64 pk = new Package64();
			pk.setTpdu(PackageUtil.hexStringToByte(this.tpdu));
			pk.setHeader(PackageUtil.hexStringToByte(this.header));
			pk.setMessagetype(PackageUtil.hexStringToByte(TYPE_ID));
			wf.log("[tpdu]=" + this.tpdu, "调试");
			wf.log("[header]=" + this.header, "调试");
			wf.log("[messagetype]=" + TYPE_ID, "调试");
			// 3、11、22、25、26、35、36、41、42、49、52、53、60、64
			String str = "bit3,bit11,bit22,bit25,bit26,bit35,bit36,bit41,bit42,bit49,bit52,bit53,bit60,bit64";
			String temp52=",bit52";
			String temp35=",bit35";
			String temp36=",bit36";
			
			String temp23=",bit23";
			String temp55=",bit55";
			String temp14=",bit14";
			if("".equals(trk2.trim()))
			{
				temp35="";
			}else{
				trk2= DesUtil.ideaioeEncryptStanderTranck(trkKey, trk2, MasterKey);
				System.out.println("密文trk2:"+trk2);
			}
			if("".equals(trk3.trim()))
			{
				temp36="";
			}else{
				trk3= DesUtil.ideaioeEncryptStanderTranck(trkKey, trk3, MasterKey);
			}
			if("".equals(des_pin.trim()))
			{
				temp52="";
			}
			if("".equals(bit23.trim()))
			{
				temp23="";
			}
			if("".equals(bit55.trim()))
			{
				temp55="";
			}
			if("".equals(bit14.trim()))
			{
				temp14="";
			}
			
			str="bit3,bit11"+temp14+",bit22"+temp23+",bit25,bit26"+temp35+temp36+",bit41,bit42,bit49"+temp52+",bit53"+temp55+",bit60,bit64";
			for (String one : str.split(",")) {
				Field filed = (Field) act.getBean(one);
				if (one.equals("bit2")) {
					filed.valueof(accountNumber);
				} else if (one.equals("bit3")) {
					filed.valueof("310000");
				} else if (one.equals("bit11")) {
					filed.valueof(serialNumber);
				} else if (one.equals("bit14")) {
					filed.valueof(bit14);
				} else if (one.equals("bit22")) {
					if("".equals(bit55.trim()))
					{
						filed.valueof("021");
					}else{
						filed.valueof("051");
					}
				} else if (one.equals("bit23")) {
					filed.valueof(bit23);
				} else if (one.equals("bit25")) {
					filed.valueof("00");
				} else if (one.equals("bit26")) {
					filed.valueof("06");
				} else if (one.equals("bit35")) {
					filed.valueof(trk2);
				} else if (one.equals("bit36")) {
					filed.valueof(trk3);
				} else if (one.equals("bit41")) {
					filed.valueof(this.PosNo);
				} else if (one.equals("bit42")) {
					filed.valueof(this.ShopCode);
				} else if (one.equals("bit49")) {
					filed.valueof("156");
				} else if (one.equals("bit52")) {
					byte[] tmp = PackageUtil.hexStringToByte(des_pin);
					filed.valueof(tmp);
				}else if (one.equals("bit53")) {
					filed.valueof("2600000000000000");
				}  else if (one.equals("bit55")) {
					filed.valueof(bit55);
				} else if (one.equals("bit60")) {
					if("".equals(bit55.trim()))
					{
						filed.valueof("01" + this.batch+"00020");
					}else{
						filed.valueof("01" + this.batch+"00050");
					}
				} else if (one.equals("bit64")) {
					byte[] tmp = PackageUtil.hexStringToByte("4632354542374636");
					filed.valueof(tmp);
				}
				pk.getData().put(filed.getFiledNumber(), filed);
			}
	
			this.bitmap = Package64.CreateBitMap(pk.getData().keySet());
			wf.log("[bitmap]=" + PackageUtil.byte2hex(this.bitmap),"调试");
	
			pk.setBitmap(this.bitmap);
	
			String tranMsg = PackageUtil.byte2hex(pk.getMessagetype())+ PackageUtil.byte2hex(pk.getBitmap());
			for (Integer one : pk.getData().keySet()) {
				if (one != 64) {
					String bitval = PackageUtil.byte2hex(pk.getData().get(one).toByte());
					tranMsg += bitval;
					wf.log("bit" + one + ":" + bitval, "调试");
				}
			}
			String macstr="";
			macstr=TestDes.MakeECBMac(MacKey, tranMsg,MasterKey);
//			System.out.println("tranMsg:" + tranMsg);
//			System.out.println("bit64:" + macstr);
			wf.log("bit64:" + macstr, "调试");
	
			Field filed = (Field) act.getBean("bit64");
			byte[] tmp = PackageUtil.hexStringToByte(macstr);
			filed.valueof(tmp);
			pk.getData().put(filed.getFiledNumber(), filed);
			byte[] pk_byteArray = pk.package64();
			ByteBuffer buff = ByteBuffer.allocate(pk_byteArray.length + 2);
			System.out.println("pk_byteArray length: " + pk_byteArray.length);
			buff.putShort((short) pk_byteArray.length);
			buff.put(pk_byteArray);
			System.out.println(PackageUtil.byte2hex(buff.array()));
			wf.log(	"----------------------------------------------------", "调试");
			wf.log("请求包:长度 " + pk_byteArray.length + " 数据 "	+ PackageUtil.byte2hex(buff.array()), "调试");
			wf.log("", "调试");
			QueryMsg = detection(buff.array());
			wf.log("响应包:长度 " + QueryMsg.length() / 2 + " 数据 "+ QueryMsg, "调试");
			if ((!QueryMsg.equals("-1")) && (!QueryMsg.equals(""))) {
				QueryMsg = "0"+ Package64.UnPackage(PackageUtil.hexStringToByte(QueryMsg), "39,54",wf);
			} else {
				return "-1_";
			}
			wf.log("佘额查询返回数据:" + QueryMsg, "调试");
			return QueryMsg;
		}catch(Exception e){
			throw e;
		}
	}
	/**
	 * 帐单费用缴费（交易）
	 * @param trk2 二磁道数据
	 * @param trk3 三磁道数据
	 * @param pin 密码
	 * @param money 交易金额
	 * @param accountNumber 卡号
	 * @param serialNumber 订单号
	 * @param bit23 IC卡序列号
	 * @param bit55 IC卡 55 域
	 * @param bit14 IC卡 序列号
	 * @return 返回消费相关信息
	 * @throws Exception
	 */
	public String BillPayment(String trk2, String trk3, String pin,String money,String accountNumber,String serialNumber,String bit23,String bit55,String bit14) throws Exception {
		try{
			String des_pin=TestDes.MakeDesPin(accountNumber, pin, PinKey,MasterKey);
			
			String QueryMsg = "";
			String TYPE_ID = "0200";
			Package64 pk = new Package64();
			pk.setTpdu(PackageUtil.hexStringToByte(this.tpdu));
			pk.setHeader(PackageUtil.hexStringToByte(this.header));
			pk.setMessagetype(PackageUtil.hexStringToByte(TYPE_ID));
			wf.log("-------------------请求包域值信息-------------------",	"调试");
			wf.log("[tpdu]=" + this.tpdu, "调试");
			wf.log("[header]=" + this.header, "调试");
			wf.log("[messagetype]=" + TYPE_ID, "调试");
			// 3、4、11、22、25、26、35、36、41、42、49、52、53、61、64
			String str = "bit3,bit4,bit11,bit22,bit25,bit26,bit35,bit36,bit41,bit42,bit49,bit52,bit53,bit61,bit64";
			String temp52=",bit52";
			String temp35 = ",bit35";
			String temp36 = ",bit36";
			String temp23=",bit23";
			String temp55=",bit55";
			String temp14=",bit14";
			if("".equals(trk2.trim()))
			{
				temp35="";
			}else{
				trk2= DesUtil.ideaioeEncryptStanderTranck(trkKey, trk2, MasterKey);
				System.out.println("密文trk2:"+trk2);
			}
			if("".equals(trk3.trim()))
			{
				temp36="";
			}else{
				trk3= DesUtil.ideaioeEncryptStanderTranck(trkKey, trk3, MasterKey);
			}
			if("".equals(des_pin.trim()))
			{
				temp52="";
			}
			if("".equals(bit23.trim()))
			{
				temp23="";
			}
			if("".equals(bit55.trim()))
			{
				temp55="";
			}
			if("".equals(bit14.trim()))
			{
				temp14="";
			}
			str="bit2,bit3,bit4,bit11"+temp14+",bit22"+temp23+",bit25,bit26"+temp35+temp36+",bit41,bit42,bit49"+temp52+",bit53"+temp55+",bit60,bit64";
			for (String one : str.split(",")) {
				Field filed = (Field) act.getBean(one);
				if (one.equals("bit2")) {
					filed.valueof(accountNumber);
				}else if (one.equals("bit3")) {
					filed.valueof("000000");
				} else if (one.equals("bit4")) {
					filed.valueof(money);
				} else if (one.equals("bit11")) {
					filed.valueof(serialNumber);
				} else if (one.equals("bit14")) {
					filed.valueof(bit14);
				} else if (one.equals("bit22")) {
					if("".equals(bit55.trim()))
					{
						filed.valueof("021");
					}else{
						filed.valueof("051");
					}
				} else if (one.equals("bit23")) {
					filed.valueof(bit23);
				} else if (one.equals("bit25")) {
					filed.valueof("00");
				} else if (one.equals("bit26")) {
					filed.valueof("06");
				} else if (one.equals("bit35")) {
					filed.valueof(trk2);
				} else if (one.equals("bit36")) {
					filed.valueof(trk3);
				} else if (one.equals("bit41")) {
					filed.valueof(this.PosNo);
				} else if (one.equals("bit42")) {
					filed.valueof(this.ShopCode);
				} else if (one.equals("bit49")) {
					filed.valueof("156");
				} else if (one.equals("bit52")) {
					byte[] tmp = PackageUtil.hexStringToByte(des_pin);
					filed.valueof(tmp);
				} else if (one.equals("bit53")) {
					filed.valueof("2600000000000000");
				} else if (one.equals("bit55")) {
					filed.valueof(bit55);
				} else if (one.equals("bit60")) {
					if("".equals(bit55.trim()))
					{
						filed.valueof("22" + this.batch+"00020");
					}else{
						filed.valueof("22" + this.batch+"00050");
					}
				} else if (one.equals("bit63")) {
					filed.valueof(PackageUtil.getCnASCII(this.operator));
				} else if (one.equals("bit64")) {
					byte[] tmp = PackageUtil.hexStringToByte("3335344331393934");
					filed.valueof(tmp);
				}
				pk.getData().put(filed.getFiledNumber(), filed);
			}
			pk.setBitmap(Package64.CreateBitMap(pk.getData().keySet()));
	
			String tranMsg = PackageUtil.byte2hex(pk.getMessagetype())
					+ PackageUtil.byte2hex(pk.getBitmap());
			for (Integer one : pk.getData().keySet()) {
				if (one != 64) {
					String bitval = PackageUtil.byte2hex(pk.getData().get(one).toByte());
					tranMsg += bitval;
					wf.log("bit" + one + ":" + bitval, "调试");
				}
			}
			// System.out.println("tranMsg:" + tranMsg);
	
			String macstr="";
			macstr=TestDes.MakeECBMac(MacKey, tranMsg,MasterKey);
			wf.log("bit64:" + macstr, "调试");
			// System.out.println("mac:" + macstr);
			Field filed = (Field) act.getBean("bit64");
			byte[] tmp = PackageUtil.hexStringToByte(macstr);
			filed.valueof(tmp);
			pk.getData().put(filed.getFiledNumber(), filed);
	
			byte[] pk_byteArray = pk.package64();
			ByteBuffer buff = ByteBuffer.allocate(pk_byteArray.length + 2);
			// System.out.println("pk_byteArray length: " + pk_byteArray.length);
			buff.putShort((short) pk_byteArray.length);
			buff.put(pk_byteArray);
			// System.out.println(PackageUtil.byte2hex(buff.array()));
	
			wf.log("----------------------------------------------------", "调试");
			wf.log("请求包:长度 " + pk_byteArray.length + " 数据 "+ PackageUtil.byte2hex(buff.array()), "调试");
			wf.log("", "调试");
			QueryMsg = detection(buff.array());
			wf.log("响应包:长度 " + QueryMsg.length() / 2 + " 数据 "+ QueryMsg, "调试");
			if ((!QueryMsg.equals("-1")) && (!QueryMsg.equals(""))) {
				QueryMsg = "0"+ Package64.UnPackage(PackageUtil.hexStringToByte(QueryMsg),"2,4,11,12,13,14,37,38,39",wf);
			} else {
				return "-1_";
			}
			wf.log("帐单费用缴费返回数据:" + QueryMsg, "调试");
			return QueryMsg;
		}catch(Exception e){
			throw e;
		}
	}

	/**
	 * 帐单缴费冲正（交易）
	 * @param trk2 二磁道数据
	 * @param trk3 三磁道数据
	 * @param money 交易金额
	 * @param accountNumber 卡号
	 * @param serialNumber 交易流水
	 * @param bit37 bit37域数据  参考号    
	 * @param bit38 bit38域数据  授权码    
	 * @param bit23 IC卡序列号
	 * @param bit55 IC卡 55 域
	 * @param bit14 IC卡 序列号
	 * @return 订单信息
	 * @throws Exception
	 */
	public String unBillPayment(String trk2, String trk3,String money,String accountNumber,String serialNumber,String bit37,String bit38,String bit23,String bit55,String bit14) throws Exception {
		try{
			String QueryMsg = "";
			String TYPE_ID = "0400";
			//this.serialNumber = unAddSerialNumber(this.serialNumber);
			Package64 pk = new Package64();
			pk.setTpdu(PackageUtil.hexStringToByte(this.tpdu));
			pk.setHeader(PackageUtil.hexStringToByte(this.header));
			pk.setMessagetype(PackageUtil.hexStringToByte(TYPE_ID));
			wf.log("-------------------请求包域值信息-------------------","调试");
			wf.log("[tpdu]=" + this.tpdu, "调试");
			wf.log("[header]=" + this.header, "调试");
			wf.log("[messagetype]=" + TYPE_ID, "调试");
			// 冲正39域为冲正原因,取值如下:
			/*
			 * 98 POS终端在时限内未能收到POS中心的应答 96 POS终端收到POS中心的批准应答消息，但由于POS机故障无法完成交易 A0
			 * POS终端对收到POS中心的批准应答消息，验证MAC出错 06 其他情况引发的冲正
			 */
			String str = "bit3,bit4,bit11,bit22,bit25,bit35,bit36,bit38,bit39,bit41,bit42,bit49,bit61,bit62,bit64";
			String temp35=",bit35";
			String temp36=",bit36";
//			String temp37 = ",bit37";
			String temp38 = ",bit38";
			
			String temp23 = ",bit23";
			String temp55 = ",bit55";
			String temp14 = ",bit14";
			if("".equals(trk2.trim()))
			{
				temp35="";
			}else{
				trk2= DesUtil.ideaioeEncryptStanderTranck(trkKey, trk2, MasterKey);
				System.out.println("密文trk2:"+trk2);
			}
			if("".equals(trk3.trim()))
			{
				temp36="";
			}else{
				trk3= DesUtil.ideaioeEncryptStanderTranck(trkKey, trk3, MasterKey);
			}
//			if("".equals(bit37))
//			{
//				temp37="";
//			}
			if("".equals(bit38))
			{
				temp38="";
			}
			if("".equals(bit23))
			{
				temp23="";
			}
			if("".equals(bit55))
			{
				temp55="";
			}
			if("".equals(bit14))
			{
				temp14="";
			}
			str="bit2,bit3,bit4,bit11"+temp14+",bit22"+temp23+",bit25"+temp35+temp36+temp38+",bit39,bit41,bit42,bit49,bit53"+temp55+",bit60,bit64";
			for (String one : str.split(",")) {
				Field filed = (Field) act.getBean(one);
				if (one.equals("bit2")) {
					filed.valueof(accountNumber);
				} else if (one.equals("bit3")) {
					filed.valueof("000000");
				} else if (one.equals("bit4")) {
					filed.valueof(money);
				} else if (one.equals("bit11")) {
					filed.valueof(serialNumber);
				} else if (one.equals("bit14")) {
					filed.valueof(bit14);
				} else if (one.equals("bit22")) {
					if("".equals(bit55.trim()))
					{
						filed.valueof("021");
					}else{
						filed.valueof("051");
					}
				} else if (one.equals("bit23")) {
					filed.valueof(bit23);
				} else if (one.equals("bit25")) {
					filed.valueof("00");
				} else if (one.equals("bit35")) {
					filed.valueof(trk2);
				} else if (one.equals("bit36")) {
					filed.valueof(trk3);
				} else if (one.equals("bit37")) {
					filed.valueof(bit37);
				} else if (one.equals("bit38")) {
					filed.valueof(bit38);
				} else if (one.equals("bit39")) {
					filed.valueof("06");
				} else if (one.equals("bit41")) {
					filed.valueof(this.PosNo);
				} else if (one.equals("bit42")) {
					filed.valueof(this.ShopCode);
				} else if (one.equals("bit49")) {
					filed.valueof("156");
				} else if (one.equals("bit53")) {
					filed.valueof("2600000000000000");
				} else if (one.equals("bit55")) {
					filed.valueof(bit55);
				} else if (one.equals("bit60")) {
					if("".equals(bit55.trim()))
					{
						filed.valueof("22" + this.batch+"00020");
					}else{
						filed.valueof("22" + this.batch+"00050");
					}
				} else if (one.equals("bit63")) {
					filed.valueof(PackageUtil.getCnASCII(this.operator));
				} else if (one.equals("bit64")) {
					byte[] tmp = PackageUtil.hexStringToByte("0000000000000000");
					filed.valueof(tmp);
				}
				pk.getData().put(filed.getFiledNumber(), filed);
			}
			pk.setBitmap(Package64.CreateBitMap(pk.getData().keySet()));
	
			String tranMsg = PackageUtil.byte2hex(pk.getMessagetype())
					+ PackageUtil.byte2hex(pk.getBitmap());
			for (Integer one : pk.getData().keySet()) {
				if (one != 64) {
					String bitval = PackageUtil.byte2hex(pk.getData().get(one)
							.toByte());
					tranMsg += bitval;
					wf.log("bit" + one + ":" + bitval, "调试");
				}
			}
//			System.out.println("tranMsg:" + tranMsg);
	
			String macstr="";
			macstr=TestDes.MakeECBMac(MacKey, tranMsg,MasterKey);
			wf.log("bit64:" + macstr, "调试");
			// System.out.println("mac:" + macstr);
			Field filed = (Field) act.getBean("bit64");
			byte[] tmp = PackageUtil.hexStringToByte(macstr);
			filed.valueof(tmp);
			pk.getData().put(filed.getFiledNumber(), filed);
	
			byte[] pk_byteArray = pk.package64();
			ByteBuffer buff = ByteBuffer.allocate(pk_byteArray.length + 2);
			// System.out.println("pk_byteArray length: " + pk_byteArray.length);
			buff.putShort((short) pk_byteArray.length);
			buff.put(pk_byteArray);
			// System.out.println(PackageUtil.byte2hex(buff.array()));
			wf.log(				"----------------------------------------------------", "调试");
			wf.log("请求包:长度 " + pk_byteArray.length + " 数据 "	+ PackageUtil.byte2hex(buff.array()), "调试");
			wf.log("", "调试");
			
			QueryMsg = detection(buff.array());
	
			wf.log("响应包:长度 " + QueryMsg.length() / 2 + " 数据 "+ QueryMsg, "调试");
			if ((!QueryMsg.equals("-1")) && (!QueryMsg.equals(""))) {
				QueryMsg = "0"+ Package64.UnPackage(PackageUtil.hexStringToByte(QueryMsg),"2,4,11,12,13,14,37,38,39,44,61",wf);
			} else {
				return "-1_";
			}
			wf.log("帐单缴费冲正返回数据:" + QueryMsg, "调试");
			return QueryMsg;
		}catch(Exception e){
			throw e;
		}
	}
	
	/**
	 * 帐单缴费冲正（交易）
	 * @param trk2 二磁道数据
	 * @param trk3 三磁道数据
	 * @param pin 卡交易密码
	 * @param money 交易金额
	 * @param accountNumber 卡号
	 * @param serialNumber 交易流水
	 * @param bit37 bit37域数据   参考号   
	 * @param bit38 bit38域数据   授权码
	 * @param serialNumber2 原订单交易流水
	 * @param bit23 IC卡序列号
	 * @param bit55 IC卡 55 域
	 * @param bit14 IC卡 序列号
	 * @return 订单信息
	 * @throws Exception
	 */
	public String undoBillPayment(String trk2, String trk3, String pin,String money,String accountNumber,String serialNumber,String bit37,String bit38,String serialNumber2,String bit23,String bit55,String bit14) throws Exception {
		try{
			String des_pin=TestDes.MakeDesPin(accountNumber, pin, PinKey,MasterKey);
			
			String QueryMsg = "";
			String TYPE_ID = "0200";
			//this.serialNumber = unAddSerialNumber(this.serialNumber);
			Package64 pk = new Package64();
			pk.setTpdu(PackageUtil.hexStringToByte(this.tpdu));
			pk.setHeader(PackageUtil.hexStringToByte(""));
			pk.setMessagetype(PackageUtil.hexStringToByte(TYPE_ID));
			wf.log("-------------------请求包域值信息-------------------","调试");
			wf.log("[tpdu]=" + this.tpdu, "调试");
			wf.log("[header]=" + this.header, "调试");
			wf.log("[messagetype]=" + TYPE_ID, "调试");
			// 冲正39域为冲正原因,取值如下:
			/*
			 * 98 POS终端在时限内未能收到POS中心的应答 96 POS终端收到POS中心的批准应答消息，但由于POS机故障无法完成交易 A0
			 * POS终端对收到POS中心的批准应答消息，验证MAC出错 06 其他情况引发的冲正
			 */
			String str = "bit3,bit4,bit11,bit22,bit25,bit26,bit35,bit36,bit38,bit39,bit41,bit42,bit49,bit61,bit62,bit64";
			String temp35=",bit35";
			String temp36=",bit36";
			String temp37 = ",bit37";
			String temp38 = ",bit38";
			
			String temp23 = ",bit23";
			String temp55 = ",bit55";
			String temp14 = ",bit14";
			if("".equals(trk2.trim()))
			{
				temp35="";
			}else{
				trk2= DesUtil.ideaioeEncryptStanderTranck(trkKey, trk2, MasterKey);
				System.out.println("密文trk2:"+trk2);
			}
			if("".equals(trk3.trim()))
			{
				temp36="";
			}else{
				trk3= DesUtil.ideaioeEncryptStanderTranck(trkKey, trk3, MasterKey);
			}
			if("".equals(bit37))
			{
				temp37="";
			}
			if("".equals(bit38))
			{
				temp38="";
			}
			if("".equals(bit23))
			{
				temp23="";
			}
			if("".equals(bit55))
			{
				temp55="";
			}
			if("".equals(bit14))
			{
				temp14="";
			}
			str="bit2,bit3,bit4,bit11"+temp14+",bit22"+temp23+",bit25,bit26"+temp35+temp36+temp37+temp38+",bit41,bit42,bit49,bit52,bit53"+temp55+",bit60,bit61,bit63,bit64";
			for (String one : str.split(",")) {
				Field filed = (Field) act.getBean(one);
				if (one.equals("bit2")) {
					filed.valueof(accountNumber);
				}else if (one.equals("bit3")) {
					filed.valueof("200000");
				} else if (one.equals("bit4")) {
					filed.valueof(money);
				} else if (one.equals("bit11")) {
					filed.valueof(serialNumber);
				} else if (one.equals("bit14")) {
					filed.valueof(bit14);
				} else if (one.equals("bit22")) {
					if("".equals(bit55.trim()))
					{
						filed.valueof("021");
					}else{
						filed.valueof("051");
					}
				} else if (one.equals("bit23")) {
					filed.valueof(bit23);
				} else if (one.equals("bit25")) {
					filed.valueof("00");
				} else if (one.equals("bit26")) {
					filed.valueof("06");
				} else if (one.equals("bit35")) {
					filed.valueof(trk2);
				} else if (one.equals("bit36")) {
					filed.valueof(trk3);
				} else if (one.equals("bit37")) {
					filed.valueof(bit37);
				} else if (one.equals("bit38")) {
					filed.valueof(bit38);
				} else if (one.equals("bit41")) {
					filed.valueof(this.PosNo);
				} else if (one.equals("bit42")) {
					filed.valueof(this.ShopCode);
				} else if (one.equals("bit49")) {
					filed.valueof("156");
				} else if (one.equals("bit52")) {
					byte[] tmp = PackageUtil.hexStringToByte(des_pin);
					filed.valueof(tmp);
				} else if (one.equals("bit53")) {
					filed.valueof("2600000000000000");
				} else if (one.equals("bit55")) {
					filed.valueof(bit55);
				} else if (one.equals("bit60")) {
					if("".equals(bit55.trim()))
					{
						filed.valueof("23" + this.batch);
					}else{
						filed.valueof("23" + this.batch+"00050");
					}
				} else if (one.equals("bit61")) {
					filed.valueof(this.batch+serialNumber2);
				} else if (one.equals("bit63")) {
					filed.valueof(PackageUtil.getCnASCII(this.operator));
				}  else if (one.equals("bit64")) {
					byte[] tmp = PackageUtil.hexStringToByte("0000000000000000");
					filed.valueof(tmp);
				}
				pk.getData().put(filed.getFiledNumber(), filed);
			}
			pk.setBitmap(Package64.CreateBitMap(pk.getData().keySet()));
	
			String tranMsg = PackageUtil.byte2hex(pk.getMessagetype())
					+ PackageUtil.byte2hex(pk.getBitmap());
			for (Integer one : pk.getData().keySet()) {
				if (one != 64) {
					String bitval = PackageUtil.byte2hex(pk.getData().get(one)
							.toByte());
					tranMsg += bitval;
					wf.log("bit" + one + ":" + bitval, "调试");
				}
			}
			System.out.println("tranMsg:" + tranMsg);
	
			String macstr="";
			macstr=TestDes.MakeECBMac(MacKey, tranMsg,MasterKey);
			wf.log("bit64:" + macstr, "调试");
			// System.out.println("mac:" + macstr);
			Field filed = (Field) act.getBean("bit64");
			byte[] tmp = PackageUtil.hexStringToByte(macstr);
			filed.valueof(tmp);
			pk.getData().put(filed.getFiledNumber(), filed);
	
			byte[] pk_byteArray = pk.package64();
			ByteBuffer buff = ByteBuffer.allocate(pk_byteArray.length + 2);
			// System.out.println("pk_byteArray length: " + pk_byteArray.length);
			buff.putShort((short) pk_byteArray.length);
			buff.put(pk_byteArray);
			// System.out.println(PackageUtil.byte2hex(buff.array()));
			wf.log(				"----------------------------------------------------", "调试");
			wf.log("请求包:长度 " + pk_byteArray.length + " 数据 "	+ PackageUtil.byte2hex(buff.array()), "调试");
			wf.log("", "调试");
			
			QueryMsg = detection(buff.array());
			if ((!QueryMsg.equals("-1")) && (!QueryMsg.equals("")))
			{
				String tpdu=QueryMsg.substring(0, 10);
				String Msg=QueryMsg.substring(10);
				QueryMsg=tpdu+header+Msg;
			}
			wf.log("响应包:长度 " + QueryMsg.length() / 2 + " 数据 "+ QueryMsg, "调试");
			if ((!QueryMsg.equals("-1")) && (!QueryMsg.equals(""))) {
				QueryMsg = "0"+ Package64.UnPackage(PackageUtil.hexStringToByte(QueryMsg),"2,4,11,12,13,14,37,38,39,44,61",wf);
			} else {
				return "-1_";
			}
			wf.log("帐单缴费冲正返回数据:" + QueryMsg, "调试");
			return QueryMsg;
		}catch(Exception e){
			throw e;
		}
	}

	//计算秘钥
	public static void  getMastKey() throws Exception{
		String fl1 = "29AD200B4F2392DCAD8045737A83EA2C";
		String fl2 = "259BF4765E5B2091E3B5E694491C1594";
		String MuKey = DesUtil.byte2hex(TestDes.XORContent(DesUtil.hexStringToByte(fl1), DesUtil.hexStringToByte(fl2)));
		System.out.println(MuKey);
		System.out.println(DesUtil.encrypt3DES("0000000000000000", MuKey));
		
//		String MuKey="11111111111111112222222222222222";
		String mastKey = jiemi(MuKey,"7FDDA933E3AC2F882605A9E11B48EB27","F0FEDF605779F605");
		System.out.println(mastKey);
		jiemi(mastKey,"1D832E6E17445C76CA3B07FA7E76DF08","3D0AB774ED85D144");
		jiemi(mastKey,"FD48F9A20D89311C3B51A47A37150083","F75E73F670329D4A");
		jiemi(mastKey,"C65E49A13DA23EA7552FC4944E490529","0425D1CF47036841");
	}
	public static String jiemi(String muKey,String masterKey,String jy)throws Exception{
		String MasterKey1= DesUtil.decode3DES(masterKey, muKey);
		String jy1 = DesUtil.encrypt3DES("0000000000000000", MasterKey1);
		System.out.println(masterKey+"\t"+MasterKey1+"\t"+jy1+"\t"+(jy.equals(jy1)));
	
		return MasterKey1;
	}
//	public static void main(String[] args) throws Exception {
//		String ShopCode="108999954113628";
//		String PosNo="18290333";
//		String batch="000001";
//		String MuKey="0C36D47D1178B24D4E35A3E7339FFFB8";
//		String MasterKey="7FDDA933E3AC2F882605A9E11B48EB27";
//		String PinKey="FD48F9A20D89311C3B51A47A37150083";
//		String MacKey="1D832E6E17445C76CA3B07FA7E76DF08";
//		String trkKey="C65E49A13DA23EA7552FC4944E490529";
//		UinpaySocketToBoss st = new UinpaySocketToBoss(ShopCode,PosNo,batch,MuKey,MasterKey,PinKey,MacKey,trkKey);
//		String accountNumber = "6210300016512078";
//		String trk2 = "6259960005135454d21032011442713500000";
//		String trk3 = "";
//		//trk2="6217900100000371909d22092201000065500";
//		trk2="6210300016512078d49121206307260000000"; //北京银行
//		String Pin="147258";
//		String des_pin=TestDes.MakeDesPin(trk2.split("d")[0], Pin, st.PinKey,st.MasterKey);
//		System.out.println("des_pin:"+des_pin);
//		//交易金额
//		String money = "000000000001";
//		String bit37="150814720054";
//		String bit38="";
//		String serialNumber="000100";
//		String serialNumber2="100002";
//		//IC卡的ID号(32长度,长度不足后补空格)
//		String ICID="";
//		//IC卡编号(4长度,长度不足前补0)
//		String ICNo="";
//		//参数下载类别
//		//		磁条卡交易采用360/361
//		// 		IC卡公钥下载交易采用370/371;
//		//		IC卡参数下载交易采用380/381;
//		//		TMS参数下载结束采用364/365;
//		//		卡BIN黑名单下载结束采用390/391
//		String ParmType="370";
//		String bit23="";
//		String bit55="";
//		String bit14="";
//		//st.serialNumber="200028";
//		//String MPOSKey="";
//		//String masKey="AA17070598B13C472F4C502D13F4D6CB";
//		//masKey=DesUtil.decode3DES(masKey,MPOSKey);
//		//System.out.println("masKey:"+masKey);
//		System.out.println("终端签到,返回:" + st.Login0800(serialNumber));
////		System.out.println("银行卡余额查询,返回:" +  st.Query(trk2, trk3, Pin,accountNumber,serialNumber,bit23,bit55,bit14));
////		System.out.println("消费,返回:" + st.BillPayment(trk2, trk3, Pin, money,accountNumber,serialNumber,bit23,bit55,bit14));
////		System.out.println("冲正,返回:" +st.unBillPayment(trk2, trk3,money,accountNumber,serialNumber, bit37, bit38,bit23,bit55,bit14));
////		System.out.println("消费撤消,返回:"+st.undoBillPayment(trk2, trk3, Pin, money,accountNumber, serialNumber,bit37, bit38, serialNumber2,bit23,bit55,bit14));
//	
////		getMastKey();
//	}
}